package com.jeff.game.tools;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

/**
 * A graphic representing a character or object. Can be given actions, such as
 * "Move Up", "Jump", etc
 */
public class Sprite
{
  private final BufferedImage image;
  private final Map<String, int[]> actions = new HashMap<>();

  private final int offsetX;
  private final int offsetY;
  private final int cols;
  private final int panelWidth;
  private final int panelHeight;

  private String currentAction;
  private int currentStep;

  /**
   * @param img Sprite sheet
   * @param offsetX Offset in the x direction to the beginning of the sprite
   *          images
   * @param offsetY Offset in the y direction to the beginning of the sprite
   *          images
   * @param rows Number of rows in sprite sheet
   * @param cols Number of columns in sprite sheet
   * @throws IOException
   */
  public Sprite(String img, int offsetX, int offsetY, int rows, int cols)
      throws IOException
  {
    this.image = ImageIO.read(new File(img));

    this.offsetX = offsetX;
    this.offsetY = offsetY;

    this.cols = cols;

    this.panelWidth = (image.getWidth() - 2 * offsetX) / cols;
    this.panelHeight = (image.getHeight() - 2 * offsetY) / rows;

    currentAction = "";
    currentStep = 0;
  }

  /**
   * Adds a new action sequence to this sprite
   * @param action Action command
   * @param panels Sequence of panels to cycle through
   */
  public void addAction(String action, int... panels)
  {
    actions.put(action, panels);
  }

  /**
   * Perform the specified action
   * @param action Action
   */
  public void perform(String action)
  {
    if (action.equals(currentAction))
    {
      int seq[] = actions.get(action);
      currentStep = (currentStep + 1) % seq.length;
    }
    else
    {
      currentAction = action;
      currentStep = 0;
    }
  }

  /**
   * @return Current sprite image
   */
  public BufferedImage getCurrent()
  {
    int panel = actions.get(currentAction)[currentStep];

    int subX = offsetX + (panel % cols) * panelWidth;
    int subY = offsetY + (panel / cols) * panelHeight;

    return image.getSubimage(subX, subY, panelWidth, panelHeight);
  }
}
